using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using IGGCore;
using IGGWindowApp.Panels;
using IGGWindowApp.Data;

namespace IGGWindowApp
{
    /// <summary>
    /// The IGG window application main form
    /// </summary>
    public partial class MainForm : Form
    {
        public delegate void GameSelectedHandler(Game game);
        public delegate void BoxSelectedHandler(Game game);
        public delegate void BoxDayChangeddHandler(bool before);
        public delegate void ModeChangeHandler(MODES newmode);
        public delegate void UpateNewsDelegate(List<News> news, string[] history);
        public delegate void UpdateSelectedGameDelegate(Game selectedGame);
        public delegate void UpdateGameListDelegate(GameList gameList);
        public delegate void AddLogDelegate(string log);
        public delegate void InitializeBasicLayoutDelegate();
        public delegate void ActivateAroundTheLeagueDelegate();
        public delegate void UpdateStadiumDelegate(WindowStadium stadium, Game SelectedGame);
        public delegate void ShowStadiumDelegate();
        public delegate void UpdateBoxscoreDelegate(Game selectedGame);
        public delegate void SwitchModeDelegate(MODES mode, object data);
        public delegate void EnableGameButtonsDelegate();
        public delegate void SetPlayersLabelsDelegate(Game selectedGame);
        public delegate void SetPlayersPicturesDelegate(Image batter, Image pitcher);
        public delegate void CleanUpLogDelegate();
        public delegate void UpdateStarsDelegate(Player[] stars);
        public delegate void SetProgressDelegate(bool progress);

        public event ModeChangeHandler modeChanged;
        public event GameSelectedHandler GameSelected;
        public event BoxSelectedHandler BoxSelected;
        public event EventHandler StadiumUpdateRequested;
        public event EventHandler MainFormLoaded;
        public event EventHandler MainFormClosing;
        public event BoxDayChangeddHandler BoxDayChanged;

        public UpateNewsDelegate myUpdateNews = null;
        public UpdateSelectedGameDelegate myUpdateSelectedGame = null;
        public UpdateGameListDelegate myUpdateGameList = null;
        public AddLogDelegate myAddLog = null;
        public InitializeBasicLayoutDelegate myInitBasicLayout = null;
        public ActivateAroundTheLeagueDelegate myActivateAroundLeague = null;
        public UpdateStadiumDelegate myUpdateStadium = null;
        public ShowStadiumDelegate myShowStadium = null;
        public UpdateBoxscoreDelegate myUpdateBoxscore = null;
        public EnableGameButtonsDelegate myEnableGameButtons = null;
        public SetPlayersLabelsDelegate mySetPlayers = null;
        public SetPlayersPicturesDelegate mySetPlayersPictures = null;
        public CleanUpLogDelegate myCleanUpLog = null;
        public SwitchModeDelegate mySwitchMode = null;
        public UpdateStarsDelegate myUpdateStars = null;
        public SetProgressDelegate mySetProgress = null;

        private GameList m_gamelist;
        private List<News> m_currentNews;
        private string[] m_currentHistory;
        private Button[] m_gameButton = new Button[16];
        private Label[] lblStadiumPlayers = new Label[13];
        private Label[] lblInningsAway = new Label[11];
        private Label[] lblInningsHome = new Label[11];
        private PictureBox pictStadium;
        private string m_awayPitchingBoxscore = "";
        private string m_homePitchingBoxscore = "";
        private bool m_inningTop = true;
        private Team m_pitchingTeam = null;
        private string m_currentStadiumName = "";

        private PanelLineup m_panelLineup;
        private PanelNews m_panelNews;
        private PanelStandings m_panelStandings;
        private PanelStats m_panelStats;
        private PanelBoards m_panelBoards;
        private PanelStars m_panelResume;

        /// <summary>
        /// Main form constructor
        /// </summary>
        public MainForm()
        {
            InitializeComponent();
            InitializeGenericUI();

            myUpdateNews = new UpateNewsDelegate(this.UpdateNews);
            myUpdateSelectedGame = new UpdateSelectedGameDelegate(this.UpdateSelectedGame);
            myUpdateGameList = new UpdateGameListDelegate(this.UpdateGameList);
            myAddLog = new AddLogDelegate(this.AddLog);
            myInitBasicLayout = new InitializeBasicLayoutDelegate(this.InitializeBasicLayout);
            myActivateAroundLeague = new ActivateAroundTheLeagueDelegate(this.ActivateAroundTheLeague);
            myUpdateStadium = new UpdateStadiumDelegate(this.UpdateStadium);
            myShowStadium = new ShowStadiumDelegate(this.ShowStadium);
            myUpdateBoxscore = new UpdateBoxscoreDelegate(this.UpdateBoxscore);
            myEnableGameButtons = new EnableGameButtonsDelegate(this.EnableGameButtons);
            mySetPlayers = new SetPlayersLabelsDelegate(this.SetPlayerLabels);
            mySetPlayersPictures = new SetPlayersPicturesDelegate(this.SetPlayersPictures);
            myCleanUpLog = new CleanUpLogDelegate(this.CleanUpLog);
            mySwitchMode = new SwitchModeDelegate(this.SwitchMode);
            myUpdateStars = new UpdateStarsDelegate(this.UpdateStars);
            mySetProgress = new SetProgressDelegate(this.SetProgress);

            m_panelLineup = new PanelLineup();
            m_panelLineup.Dock = DockStyle.Fill;
            m_panelLineup.Visible = false;
            this.panelContent.Controls.Add(m_panelLineup);

            m_panelNews = new PanelNews();
            m_panelNews.Dock = DockStyle.Fill;
            m_panelNews.Visible = false;
            this.panelContent.Controls.Add(m_panelNews);

            m_panelStandings = new PanelStandings();
            m_panelStandings.Dock = DockStyle.Fill;
            m_panelStandings.Visible = false;
            this.panelContent.Controls.Add(m_panelStandings);

            m_panelStats = new PanelStats();
            m_panelStats.Dock = DockStyle.Fill;
            m_panelStats.Visible = false;
            this.panelContent.Controls.Add(m_panelStats);

            m_panelBoards = new PanelBoards();
            m_panelBoards.Dock = DockStyle.Fill;
            m_panelBoards.Visible = false;
            m_panelBoards.dayChanged += new PanelBoards.DayChangeHandler(m_panelBoards_dayChanged);
            m_panelBoards.boxSelected += new PanelBoards.BoxSelectionHandler(m_panelBoards_boxSelected);
            this.panelContent.Controls.Add(m_panelBoards);

            m_panelResume = new PanelStars();
            m_panelResume.Dock = DockStyle.Fill;
            m_panelResume.Visible = false;
            this.panelTabBoxscoresContainer.Controls.Add(this.m_panelResume);

            this.ActiveControl = m_gameButton[0];
        }

        private void SetProgress(bool progress)
        {
            //pctLoading.Visible = progress;
        }

        private void m_panelBoards_boxSelected(Game game)
        {
            tabControlBoxscore.Visible = false;
            m_panelResume.Visible = true;
            BoxSelected(game);
        }

        private void m_panelBoards_dayChanged(bool before)
        {
            BoxDayChanged(before);
        }

        private void UpdateStars(Player[] stars)
        {
            m_panelResume.UpdateStars(stars);
        }

        /// <summary>
        /// Switch the mode
        /// </summary>
        private void SwitchMode(MODES mode, object data)
        {
            switch (mode)
            {
                case MODES.LINEUP:
                    this.m_panelLineup.Visible = true;
                    this.pictStadium.Visible = false;
                    this.m_panelNews.Visible = false;
                    this.m_panelStandings.Visible = false;
                    this.m_panelStats.Visible = false;
                    this.m_panelBoards.Visible = false;
                    if (data != null)
                    {
                        for (int i = 0; i < 13; i++)
                        {
                            lblStadiumPlayers[i].Visible = false;
                        }
                        lblStadiumNameTitle.Text = "Lineups";
                        lblStadiumNameTitle.Refresh();

                        Game selGame = data as Game;
                        this.m_panelLineup.SetData(selGame);
                    }
                    break;
                case MODES.FIELD:
                    tabControlBoxscore.Visible = true;
                    m_panelResume.Visible = false;
                    this.m_panelLineup.Visible = false;
                    this.pictStadium.Visible = true;
                    this.m_panelNews.Visible = false;
                    this.m_panelStandings.Visible = false;
                    this.m_panelStats.Visible = false;
                    this.m_panelBoards.Visible = false;
                    if (data != null)
                    {
                        SetPlayerLabels(data as Game);
                        lblStadiumNameTitle.Text = m_currentStadiumName;
                        lblStadiumNameTitle.Refresh();
                    }
                    break;
                case MODES.NEWS:
                    this.m_panelLineup.Visible = false;
                    this.pictStadium.Visible = false;
                    this.m_panelStandings.Visible = false;
                    this.m_panelNews.Visible = true;
                    this.m_panelStats.Visible = false;
                    this.m_panelBoards.Visible = false;
                    for (int i = 0; i < 13; i++)
                    {
                        lblStadiumPlayers[i].Visible = false;
                    }
                    lblStadiumNameTitle.Text = "Baseball News";
                    lblStadiumNameTitle.Refresh();

                    List<News> news = data as List<News>;
                    this.m_panelNews.SetData(news);
                    break;
                case MODES.STANDINGS:
                    this.m_panelLineup.Visible = false;
                    this.pictStadium.Visible = false;
                    this.m_panelNews.Visible = false;
                    this.m_panelStandings.Visible = true;
                    this.m_panelStats.Visible = false;
                    this.m_panelBoards.Visible = false;
                    for (int i = 0; i < 13; i++)
                    {
                        lblStadiumPlayers[i].Visible = false;
                    }
                    lblStadiumNameTitle.Text = "Standings";
                    lblStadiumNameTitle.Refresh();

                    Scoreboard board = data as Scoreboard;
                    this.m_panelStandings.SetData(board);
                    break;
                case MODES.STATS:
                    this.m_panelLineup.Visible = false;
                    this.pictStadium.Visible = false;
                    this.m_panelNews.Visible = false;
                    this.m_panelStandings.Visible = false;
                    this.m_panelStats.Visible = true;
                    this.m_panelBoards.Visible = false;
                    for (int i = 0; i < 13; i++)
                    {
                        lblStadiumPlayers[i].Visible = false;
                    }
                    lblStadiumNameTitle.Text = "Statistics";
                    lblStadiumNameTitle.Refresh();
                    this.m_panelStats.SetData(data as Scoreboard);
                    break;
                case MODES.SCOREBOARDS:
                    this.m_panelLineup.Visible = false;
                    this.pictStadium.Visible = false;
                    this.m_panelNews.Visible = false;
                    this.m_panelStandings.Visible = false;
                    this.m_panelStats.Visible = false;
                    this.m_panelBoards.Visible = true;
                    for (int i = 0; i < 13; i++)
                    {
                        lblStadiumPlayers[i].Visible = false;
                    }
                    lblStadiumNameTitle.Text = "Scores";
                    lblStadiumNameTitle.Refresh();

                    Scoreboard boardz = data as Scoreboard;
                    this.m_panelBoards.SetData(boardz);
                    break;
            }
        }

        /// <summary>
        /// Add a log
        /// </summary>
        private void AddLog(string log)
        {
            txtLog.Text += (log + Environment.NewLine);
            txtLog.Refresh();
        }

        /// <summary>
        /// Clean up the log
        /// </summary>
        private void CleanUpLog()
        {
            txtLog.Text = "";
            txtLog.Refresh();
        }

        /// <summary>
        /// Enable game buttons
        /// </summary>
        private void EnableGameButtons()
        {
            for (int i = 0; i < 16; i++)
            {
                m_gameButton[i].Enabled = true;
            }
        }

        /// <summary>
        /// Initialize basic layout
        /// </summary>
        private void InitializeBasicLayout()
        {
            pctTeamAway.Visible = true;
            pctTeamHome.Visible = true;
            lblAroundTheLeagueTitle.Text = "Around The League";
            lblNewsTitle.Text = "News";
            lblStadiumNameTitle.Text = "Welcome to the Window IGG Application";
        }

        /// <summary>
        /// Override the onLoad event manager
        /// </summary>
        protected override void OnLoad(EventArgs args)
        {
            base.OnLoad(args);
            Application.Idle += new EventHandler(OnLoaded);
        }

        /// <summary>
        /// Manage the OnLoaded event.
        /// Throws the MainFormLoaded event for the manager
        /// </summary>
        private void OnLoaded(object sender, EventArgs args)
        {
            Application.Idle -= new EventHandler(OnLoaded);
            MainFormLoaded(this, null);
        }

        /// <summary>
        /// Initialize the game buttons
        /// </summary>
        private void InitializeGameButtons()
        {
            panelGameButtonsContainer.SuspendLayout();
            int yPost = 4;
            for (int i = 0; i < 16; i++)
            {
                m_gameButton[i] = new Button();
                m_gameButton[i].Font = new Font("Franklin Gothic Demi", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                m_gameButton[i].Location = new Point(1, yPost);
                m_gameButton[i].Name = "btnGame"+i;
                m_gameButton[i].Size = new Size(115, 26);
                m_gameButton[i].TabIndex = i;
                m_gameButton[i].Text = "";
                m_gameButton[i].TextAlign = ContentAlignment.MiddleLeft;
                m_gameButton[i].UseVisualStyleBackColor = true;
                m_gameButton[i].Enabled = false;
                m_gameButton[i].Click += new EventHandler(this.GameButtonClick);
                panelGameButtonsContainer.Controls.Add(m_gameButton[i]);
                yPost += 32;
            }
            panelGameButtonsContainer.ResumeLayout(false);
        }

        /// <summary>
        /// Initialize the stadium labels
        /// </summary>
        private void InitializeStadiumUI()
        {
            panelContent.SuspendLayout();
            for (int i = 0; i < 13; i++)
            {
                lblStadiumPlayers[i] = new Label();
                lblStadiumPlayers[i].BackColor = Color.White;
                lblStadiumPlayers[i].BorderStyle = BorderStyle.FixedSingle;
                lblStadiumPlayers[i].Font = new Font("Franklin Gothic Book", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                lblStadiumPlayers[i].Location = new System.Drawing.Point(324, 216);
                lblStadiumPlayers[i].Name = "lblPlayer" + i;
                lblStadiumPlayers[i].Size = new System.Drawing.Size(100, 21);
                lblStadiumPlayers[i].TabIndex = 14;
                lblStadiumPlayers[i].Text = "Player";
                lblStadiumPlayers[i].TextAlign = ContentAlignment.MiddleCenter;
                lblStadiumPlayers[i].Visible = false;
                panelContent.Controls.Add(lblStadiumPlayers[i]);
            }
            pictStadium = new PictureBox();
            pictStadium.BackColor = System.Drawing.SystemColors.Control;
            pictStadium.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            pictStadium.Dock = System.Windows.Forms.DockStyle.Fill;
            pictStadium.Location = new System.Drawing.Point(5, 29);
            pictStadium.Name = "pictMainStadium";
            pictStadium.Size = new System.Drawing.Size(671, 482);
            pictStadium.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
            pictStadium.TabIndex = 6;
            pictStadium.TabStop = false;
            pictStadium.DoubleClick += new EventHandler(pictStadium_DoubleClick);
            panelContent.Controls.Add(pictStadium);

            panelContent.ResumeLayout(false);
        }

        /// <summary>
        /// Manage the double-click on the stadium pic
        /// </summary>
        private void pictStadium_DoubleClick(object sender, EventArgs e)
        {
            StadiumUpdateRequested(this, null);
        }

        /// <summary>
        /// Update the single news
        /// </summary>
        private void UpdateNews(List<News> news, string[] history)
        {
            m_currentNews = news;
            m_currentHistory = history;
            txtNews.Text = news[0].Content;
            txtNews.Refresh();
            timerNews.Enabled = true;
        }

        /// <summary>
        /// Activate Around The League Ticker
        /// </summary>
        private void ActivateAroundTheLeague()
        {
            timerAroundTheLeague.Enabled = true;
        }

        /// <summary>
        /// Set players positions on the stadium image
        /// </summary>
        private void SetPlayerLabels(Game selectedGame)
        {
            int[][] pitchingColors = new int[2][];
            int[][] battingColors = new int[2][];
            Team pitchingTeam = selectedGame.HomeTeam;
            Team battingTeam = selectedGame.AwayTeam;
            if (selectedGame.Status.InningTop == false)
            {
                pitchingTeam = selectedGame.AwayTeam;
                pitchingColors[0] = pitchingTeam.TeamID.BackColorAway;
                pitchingColors[1] = pitchingTeam.TeamID.ForeColorAway;
                battingTeam = selectedGame.HomeTeam;
                battingColors[0] = battingTeam.TeamID.BackColor;
                battingColors[1] = battingTeam.TeamID.ForeColor;
            }
            else
            {
                pitchingColors[0] = pitchingTeam.TeamID.BackColor;
                pitchingColors[1] = pitchingTeam.TeamID.ForeColor;
                battingColors[0] = battingTeam.TeamID.BackColorAway;
                battingColors[1] = battingTeam.TeamID.ForeColorAway;
            }

            Color pitchingColor = Color.FromArgb(pitchingColors[0][0],
                pitchingColors[0][1], pitchingColors[0][2]);
            Color pitchingForeColor = Color.FromArgb(pitchingColors[1][0],
                pitchingColors[1][1], pitchingColors[1][2]);

            Color battingColor = Color.FromArgb(battingColors[0][0],
                battingColors[0][1], battingColors[0][2]);
            Color battingForeColor = Color.FromArgb(battingColors[1][0],
                battingColors[1][1], battingColors[1][2]);
            for (int i = 0; i < 13; i++)
            {
                if (i < 9)
                {
                    lblStadiumPlayers[i].BackColor = pitchingColor;
                    lblStadiumPlayers[i].ForeColor = pitchingForeColor;
                }
                else
                {
                    lblStadiumPlayers[i].BackColor = battingColor;
                    lblStadiumPlayers[i].ForeColor = battingForeColor;
                }
            }

            SetPlayer(selectedGame.Status.CurrentBatter, lblStadiumPlayers[CoreConstants.POSITION_BATTER]);
            for (int i = 0; i < 9; i++)
            {
                SetPlayer(pitchingTeam.Defense[i], lblStadiumPlayers[i]);
                lblStadiumPlayers[i].Visible = true;
                lblStadiumPlayers[i].Refresh();
            }
            SetRunner(selectedGame.Status.RunnersOnBase[0], lblStadiumPlayers[10]);
            SetRunner(selectedGame.Status.RunnersOnBase[1], lblStadiumPlayers[11]);
            SetRunner(selectedGame.Status.RunnersOnBase[2], lblStadiumPlayers[12]);

            timerAtTheMound.Enabled = true;
        }

        /// <summary>
        /// Set the batter and pitcher pictures
        /// </summary>
        private void SetPlayersPictures(Image batter, Image pitcher)
        {
            pbAtBat.Image = batter;
            pbAtBat.Refresh();
            pbAtTheMound.Image = pitcher;
            pbAtTheMound.Refresh();
            lblOnTheMoundTitle.Text = "On The Mound For The " + m_pitchingTeam.Name;
            lblAtBatTitle.Text = "At Bat";
        }

        /// <summary>
        /// Set the runner text and visibility
        /// </summary>
        private void SetRunner(Player runner, Label label)
        {
            if (runner != null)
            {
                label.Visible = true;
                label.Text = runner.PartialName;
            }
            else
            {
                label.Visible = false;
            }
        }

        /// <summary>
        /// Update the boxscore panels
        /// </summary>
        private void UpdateBoxscore(Game selectedGame)
        {
            StringBuilder sb = new StringBuilder();
            foreach (Player player in selectedGame.Boxscore.AwayBatting)
            {
                string prefix = "";
                if (String.IsNullOrEmpty(player.BO) == false)
                {
                    if (player.BO[2] == '1')
                    {
                        prefix = "- ";
                    }
                    else if (player.BO[2] == '2')
                    {
                        prefix = "-- ";
                    }
                    else if (player.BO[2] == '3')
                    {
                        prefix = "--- ";
                    }
                }
                sb.Append(ToolBox.GetFormattedStringPadRight(prefix + player.LastName, 16));
                sb.Append(ToolBox.GetFormattedStringPadLeft(player.Ab.ToString(), 2));
                sb.Append(" ");
                sb.Append(ToolBox.GetFormattedStringPadLeft(player.R.ToString(), 2));
                sb.Append(" ");
                sb.Append(ToolBox.GetFormattedStringPadLeft(player.Hits.ToString(), 2));
                sb.Append(" ");
                sb.Append(ToolBox.GetFormattedStringPadLeft(player.RBI.ToString(), 3));
                sb.Append("   ");
                sb.Append(player.AVG.ToString() + Environment.NewLine);
            }

            txtBoxscoreAway.Text = sb.ToString();

            StringBuilder sbHome = new StringBuilder();
            foreach (Player player in selectedGame.Boxscore.HomeBatting)
            {
                string prefix = "";
                if (String.IsNullOrEmpty(player.BO) == false)
                {
                    if (player.BO[2] == '1')
                    {
                        prefix = "- ";
                    }
                    else if (player.BO[2] == '2')
                    {
                        prefix = "-- ";
                    }
                    else if (player.BO[2] == '3')
                    {
                        prefix = "--- ";
                    }
                }
                sbHome.Append(ToolBox.GetFormattedStringPadRight(prefix + player.LastName, 16));
                sbHome.Append(ToolBox.GetFormattedStringPadLeft(player.Ab.ToString(), 2));
                sbHome.Append(" ");
                sbHome.Append(ToolBox.GetFormattedStringPadLeft(player.R.ToString(), 2));
                sbHome.Append(" ");
                sbHome.Append(ToolBox.GetFormattedStringPadLeft(player.Hits.ToString(), 2));
                sbHome.Append(" ");
                sbHome.Append(ToolBox.GetFormattedStringPadLeft(player.RBI.ToString(), 3));
                sbHome.Append("  ");
                sbHome.Append(player.AVG.ToString() + Environment.NewLine);
            }
            txtBoxscoreHome.Text = sbHome.ToString();
            StringBuilder sbAwayP = new StringBuilder();
            foreach (Player player in selectedGame.Boxscore.AwayPitching)
            {
                if (player.Report == null)
                {
                    sbAwayP.Append(ToolBox.GetFormattedStringPadRight(player.LastName, 21));
                }
                else
                {
                    sbAwayP.Append(ToolBox.GetFormattedStringPadRight(player.LastName + " " + player.Report, 21));
                }
                sbAwayP.Append(player.IP);
                sbAwayP.Append(" ");
                sbAwayP.Append(ToolBox.GetFormattedStringPadLeft(player.Hits.ToString(), 2));
                sbAwayP.Append(" ");
                sbAwayP.Append(ToolBox.GetFormattedStringPadLeft(player.R.ToString(), 2));
                sbAwayP.Append(" ");
                sbAwayP.Append(ToolBox.GetFormattedStringPadLeft(player.EarnedRuns.ToString(), 3));
                sbAwayP.Append(" ");
                sbAwayP.Append(ToolBox.GetFormattedStringPadLeft(player.BB.ToString(), 3));
                sbAwayP.Append(" ");
                sbAwayP.Append(ToolBox.GetFormattedStringPadLeft(player.StrikeOuts.ToString(), 3));
                sbAwayP.Append("   ");
                sbAwayP.Append(player.ERA.ToString());
                sbAwayP.Append(Environment.NewLine);
            }
            lblOnTheMoundTitle.Text = selectedGame.AwayTeam.City + " Pitching";
            m_awayPitchingBoxscore = sbAwayP.ToString();
            txtBoxPitchingA.Text = sbAwayP.ToString();

            txtBoxPitchingB.Visible = true;
            StringBuilder sbHomeP = new StringBuilder();
            foreach (Player player in selectedGame.Boxscore.HomePitching)
            {
                if (player.Report == null)
                {
                    sbHomeP.Append(ToolBox.GetFormattedStringPadRight(player.LastName, 21));
                }
                else
                {
                    sbHomeP.Append(ToolBox.GetFormattedStringPadRight(player.LastName + " " + player.Report, 21));
                }
                sbHomeP.Append(player.IP);
                sbHomeP.Append(" ");
                sbHomeP.Append(ToolBox.GetFormattedStringPadLeft(player.Hits.ToString(), 2));
                sbHomeP.Append(" ");
                sbHomeP.Append(ToolBox.GetFormattedStringPadLeft(player.R.ToString(), 2));
                sbHomeP.Append(" ");
                sbHomeP.Append(ToolBox.GetFormattedStringPadLeft(player.EarnedRuns.ToString(), 3));
                sbHomeP.Append(" ");
                sbHomeP.Append(ToolBox.GetFormattedStringPadLeft(player.BB.ToString(), 3));
                sbHomeP.Append(" ");
                sbHomeP.Append(ToolBox.GetFormattedStringPadLeft(player.StrikeOuts.ToString(), 3));
                sbHomeP.Append("   ");
                sbHomeP.Append(player.ERA.ToString());
                sbHomeP.Append(Environment.NewLine);
            }
            txtBoxPitchingB.Text = sbHomeP.ToString();
            lblAtBatTitle.Text = selectedGame.HomeTeam.City + " Pitching";
            m_homePitchingBoxscore = sbHomeP.ToString();
        }

        /// <summary>
        /// Update the buttons color
        /// </summary>
        private void UpdateButtonColor(Game selectedGame)
        {
            for (int i = 0; i < 16; i++)
            {
                if (m_gameButton[i].Visible)
                {
                    Game indGame = m_gameButton[i].Tag as Game;
                    if (indGame.Id == selectedGame.Id)
                    {
                        m_gameButton[i].BackColor = WindowConstants.SELECTED_GAME_BUTTON_COLOR;
                        this.ActiveControl = m_gameButton[i];
                    }
                    else
                    {
                        m_gameButton[i].BackColor = SystemColors.Control;
                    }
                    m_gameButton[i].Refresh();
                }
            }
        }

        /// <summary>
        /// Update the stadium panel
        /// </summary>
        private void UpdateStadium(WindowStadium stadium, Game SelectedGame)
        {
            lblStadiumNameTitle.Text = stadium.Name;
            m_currentStadiumName = stadium.Name;
            lblStadiumNameTitle.Refresh();

            int hour = DateTime.Now.Hour;
            hour = hour - SelectedGame.HomeTeam.TeamID.TimeZoneDiff;
            if (SelectedGame.Status.Indicator.Category == Indicator.IndicatorCategoy.INTERRUPTED)
            {
                pictStadium.Image = stadium.StadiumImageRain;
            }
            else if (SelectedGame.Status.Indicator.Category == Indicator.IndicatorCategoy.IN_PROGRESS)
            {
                if (hour < 18)
                {
                    pictStadium.Image = stadium.StadiumImageDay;
                    for (int i = 0; i < 13; i++)
                    {
                        lblStadiumPlayers[i].Location = stadium.StadiumDayPositions[i];
                    }
                }
                else if (hour < 19)
                {
                    pictStadium.Image = stadium.StadiumImageDusk;
                    for (int i = 0; i < 13; i++)
                    {
                        lblStadiumPlayers[i].Location = stadium.StadiumDuskPositions[i];
                    }
                }
                else
                {
                    pictStadium.Image = stadium.StadiumImageNight;
                    for (int i = 0; i < 13; i++)
                    {
                        lblStadiumPlayers[i].Location = stadium.StadiumNightPositions[i];
                    }
                }
            }
            else
            {
                pictStadium.Image = stadium.StadiumImageEmpty;
            }
            pictStadium.Refresh();
        }

        /// <summary>
        /// Show the Stadiumn and the players
        /// </summary>
        private void ShowStadium()
        {
            if (pictStadium.Image == null)
            {
            }
            panelLogContainer.Visible = false;
            pictStadium.Visible = true;
            pictStadium.Refresh();
        }

        /// <summary>
        /// Set UI Layout controls visibility depending on the game progress
        /// </summary>
        /// <param name="inProgress"></param>
        private void SetControlsVisibility(bool inProgress)
        {
            txtBoxPitchingA.Visible = !inProgress;
            txtBoxPitchingB.Visible = !inProgress;

            pbAtTheMound.Visible = inProgress;
            lblOnTheMound.Visible = inProgress;
            lblAtBat.Visible = inProgress;
            pbAtBat.Visible = inProgress;

            //lblStatsBatterA.Text = "";
            //lblStatsBatterB.Text = "";
            //lblStatsPitcherA.Text = "";
            //lblStatsPitcherB.Text = "";

            //lblRunsAway.Text = "";
            //lblRunsHome.Text = "";
            //lblHitsAway.Text = "";
            //lblHitsHome.Text = "";
            //lblErrorsAway.Text = "";
            //lblErrorsHome.Text = "";
        }

        /// <summary>
        /// Set the linescore for a specified game
        /// </summary>
        private void SetLinescore(Game game)
        {
            if (game.Linescore != null)
            {
                lblRunsAway.Text = game.Linescore.GetAwayLineScore().Runs.ToString();
                lblRunsHome.Text = game.Linescore.GetHomeLineScore().Runs.ToString();
                lblHitsAway.Text = game.Linescore.GetAwayLineScore().Hits.ToString();
                lblHitsHome.Text = game.Linescore.GetHomeLineScore().Hits.ToString();
                lblErrorsAway.Text = game.Linescore.GetAwayLineScore().Errors.ToString();
                lblErrorsHome.Text = game.Linescore.GetHomeLineScore().Errors.ToString();

                int innCount = game.Status.Inning;
                for (int i = 0; i < 11; i++)
                {
                    if (i < innCount)
                    {
                        if (game.Linescore.Innings[i].Away > -1)
                        {
                            lblInningsAway[i].Text = game.Linescore.Innings[i].Away.ToString();
                        }
                        else
                        {
                            lblInningsAway[i].Text = "";
                        }
                        if (game.Linescore.Innings[i].Home > -1)
                        {
                            lblInningsHome[i].Text = game.Linescore.Innings[i].Home.ToString();
                        }
                        else
                        {
                            lblInningsHome[i].Text = "";
                        }
                    }
                    else
                    {
                        lblInningsAway[i].Text = "";
                        lblInningsHome[i].Text = "";
                    }
                }
            }
            else
            {
                for (int i = 0; i < 11; i++)
                {
                    lblInningsAway[i].Text = "";
                    lblInningsHome[i].Text = "";
                }
            }
        }

        /// <summary>
        /// Update the selected game
        /// </summary>
        /// <param name="selectedGame"></param>
        private void UpdateSelectedGame(Game selectedGame)
        {
            tabControlBoxscore.TabPages[0].Text = selectedGame.AwayTeam.City;
            tabControlBoxscore.TabPages[1].Text = selectedGame.HomeTeam.City;
            tabControlBoxscore.Visible = true;
            m_inningTop = selectedGame.Status.InningTop;

            UpdateButtonColor(selectedGame);

            lblGameTitle.Text = selectedGame.AwayTeam.City + " @ " + selectedGame.HomeTeam.City;
            lblGameTitle.Refresh();

            lblTeamAway.Text = selectedGame.AwayTeam.City;
            lblTeamAway.Refresh();
            pctTeamAway.Image = listLogos.Images[selectedGame.AwayTeam.City];
            pctTeamAway.Refresh();
            lblTeamHome.Text = selectedGame.HomeTeam.City;
            lblTeamHome.Refresh();
            pctTeamHome.Image = listLogos.Images[selectedGame.HomeTeam.City];
            pctTeamHome.Refresh();

            if (selectedGame.Status.Indicator.Category == Indicator.IndicatorCategoy.TERMINATED)
            {
                lblCurrentInning.Text = "Final";
                SetControlsVisibility(false);
            }
            else if (selectedGame.Status.Indicator.Category == Indicator.IndicatorCategoy.NEXT)
            {
                lblCurrentInning.Text = selectedGame.StartTime + " " + selectedGame.AmPm;
                SetControlsVisibility(false);
            }
            else if (selectedGame.Status.Indicator.Category == Indicator.IndicatorCategoy.WARMUP)
            {
                lblCurrentInning.Text = selectedGame.StartTime + " " + selectedGame.AmPm;
                SetControlsVisibility(false);
            }
            else if (selectedGame.Status.Indicator.Category == Indicator.IndicatorCategoy.INTERRUPTED)
            {
                lblCurrentInning.Text = "Rain";
                SetControlsVisibility(false);
            }
            else if (selectedGame.Status.Indicator.Category == Indicator.IndicatorCategoy.IN_PROGRESS)
            {
                SetControlsVisibility(true);
                string prefix = "Bottom of the ";
                Team battingTeam = selectedGame.HomeTeam;
                Team pitchingTeam = selectedGame.AwayTeam;
                
                if (selectedGame.Status.InningTop)
                {
                    prefix = "Top of the ";
                    battingTeam = selectedGame.AwayTeam;
                    pitchingTeam = selectedGame.HomeTeam;
                }
                m_pitchingTeam = pitchingTeam;
                prefix += selectedGame.Status.Inning.ToString();
                lblCurrentInning.Text = prefix;
            }
            SetLinescore(selectedGame);

            if (selectedGame.Status.CurrentBatter != null)
            {
                lblAtBat.Text = selectedGame.Status.CurrentBatter.FullName;
                string playerId = selectedGame.Status.CurrentBatter.Id;
                if (selectedGame.Status.InningTop)
                {
                    foreach (Player player in selectedGame.Boxscore.AwayBatting)
                    {
                        if (player.Id == playerId)
                        {
                            lblStatsBatterA.Text = player.Hits.ToString() + " / " + player.Ab.ToString();
                            lblStatsBatterB.Text = player.RBI + " rbi, " + player.R + " runs";
                            lblStatsBatterC.Text = "avg: " + player.AVG;
                            break;
                        }
                    }
                }
                else
                {
                    foreach (Player player in selectedGame.Boxscore.HomeBatting)
                    {
                        if (player.Id == playerId)
                        {
                            lblStatsBatterA.Text = player.Hits.ToString() + " / " + player.Ab.ToString();
                            lblStatsBatterB.Text = player.RBI + " rbi, " + player.R + " runs";
                            lblStatsBatterC.Text = "avg: " + player.AVG;
                            break;
                        }
                    }
                }
            }
            if (selectedGame.Status.CurrentPitcher != null)
            {
                lblOnTheMound.Text = selectedGame.Status.CurrentPitcher.FullName;
                string playerId = selectedGame.Status.CurrentPitcher.Id;
                if (selectedGame.Status.InningTop)
                {
                    foreach (Player player in selectedGame.Boxscore.HomePitching)
                    {
                        if (player.Id == playerId)
                        {
                            lblStatsPitcherA.Text = "ip: " + player.IP + ", hits: "
                                + player.Hits + ", er: " + player.EarnedRuns;
                            lblStatsPitcherB.Text = "era: " + player.ERA;
                            break;
                        }
                    }
                }
                else
                {
                    foreach (Player player in selectedGame.Boxscore.AwayPitching)
                    {
                        if (player.Id == playerId)
                        {
                            lblStatsPitcherA.Text = "ip: " + player.IP + ", hits: "
                                + player.Hits + ", er: " + player.EarnedRuns;
                            lblStatsPitcherB.Text = "era: " + player.ERA;
                            break;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Set a player text and visibility
        /// </summary>
        private void SetPlayer(Player player, Label label)
        {
            if (player != null)
            {
                label.Text = player.PartialName;
                label.Visible = true;
            }
            else
            {
                label.Visible = false;
            }
        }

        /// <summary>
        /// Initialize the dynamically created UI elements
        /// </summary>
        private void InitializeGenericUI()
        {
            InitializeGameButtons();
            InitializeStadiumUI();
            for (int i = 0; i < 11; i++)
            {
                lblInningsAway[i] = CreateTableLabel(ContentAlignment.MiddleCenter, Color.White, 9.75F, true);
                tableScoreboard.Controls.Add(lblInningsAway[i], i, 1);
                lblInningsHome[i] = CreateTableLabel(ContentAlignment.MiddleCenter, Color.White, 9.75F, true);
                tableScoreboard.Controls.Add(lblInningsHome[i], i, 2);
            }
        }

        /// <summary>
        /// Create a table label
        /// </summary>
        private Label CreateTableLabel(ContentAlignment textAlign, Color textColor, float textSize, bool bold)
        {
            Label label = new Label();
            label.Dock = DockStyle.Fill;
            label.TextAlign = textAlign;
            label.ForeColor = textColor;
            label.Text = "";
            label.AutoSize = true;
            if (bold == true)
            {
                label.Font = new System.Drawing.Font("Franklin Gothic Book", textSize, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            }
            else
            {
                label.Font = new System.Drawing.Font("Franklin Gothic Book", textSize, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            }
            return label;
        }

        /// <summary>
        /// Update the game button list
        /// </summary>
        private void UpdateGameList(GameList gamelist)
        {
            m_gamelist = gamelist;
            for (int i = 0; i < 16; i++)
            {
                SetButton(this.m_gameButton[i], m_gamelist, i);
            }
        }

        /// <summary>
        /// Set a game button properly
        /// </summary>
        private void SetButton(Button button, GameList list, int index)
        {
            if (list.Games.Count > index)
            {
                if (list.Games[index].Status.Indicator.Category == Indicator.IndicatorCategoy.TERMINATED)
                {
                    button.Text = "F - " + list.Games[index].AwayTeam.Abbrv.ToUpper()
                        + " vs " + list.Games[index].HomeTeam.Abbrv.ToUpper();
                }
                else if (list.Games[index].Status.Indicator.Category == Indicator.IndicatorCategoy.INTERRUPTED)
                {
                    button.Text = "R - " + list.Games[index].AwayTeam.Abbrv.ToUpper()
                        + " vs " + list.Games[index].HomeTeam.Abbrv.ToUpper();
                }
                else if (list.Games[index].Status.Indicator.Category == Indicator.IndicatorCategoy.WARMUP)
                {

                    button.Text = list.Games[index].StartTime + " - " + list.Games[index].AwayTeam.Abbrv.ToUpper()
                        + " vs " + list.Games[index].HomeTeam.Abbrv.ToUpper();
                }
                else if (list.Games[index].Status.Indicator.Category == Indicator.IndicatorCategoy.NEXT)
                {
                    button.Text = list.Games[index].StartTime + " - " + list.Games[index].AwayTeam.Abbrv.ToUpper()
                        + " vs " + list.Games[index].HomeTeam.Abbrv.ToUpper();
                }
                else if (list.Games[index].Status.Indicator.Category == Indicator.IndicatorCategoy.IN_PROGRESS)
                {
                    button.Text = list.Games[index].Status.Inning + " - " + list.Games[index].AwayTeam.Abbrv.ToUpper()
                        + " vs " + list.Games[index].HomeTeam.Abbrv.ToUpper();
                }
                button.Tag = list.Games[index];
            }
            else
            {
                button.Visible = false;
            }
        }

        /// <summary>
        /// Manage a click of a game button.
        /// It triggers a GameSelected event.
        /// </summary>
        private void GameButtonClick(object sender, EventArgs e)
        {
            txtLog.Text = "";
            lblStadiumNameTitle.Text = "Loading...";
            lblStadiumNameTitle.Refresh();
            timerAtTheMound.Enabled = false;
            timerAtTheBat.Enabled = false;

            Button gameButton = sender as Button;
            gameButton.BackColor = WindowConstants.SELECTED_GAME_BUTTON_COLOR;

            for (int i = 0; i < 16; i++)
            {
                if (m_gameButton[i] != gameButton && m_gameButton[i].BackColor != SystemColors.Control)
                {
                    m_gameButton[i].BackColor = SystemColors.Control;
                    m_gameButton[i].Refresh();
                }
            }

            for (int i = 0; i < 13; i++)
            {
                lblStadiumPlayers[i].Visible = false;
            }
            pictStadium.Visible = false;
            pictStadium.Refresh();
            panelLogContainer.Visible = true;
            panelLogContainer.Refresh();

            GameSelected(gameButton.Tag as Game);
        }


        /// <summary>
        /// Update the game news panel
        /// </summary>
        private void timerNews_Tick(object sender, EventArgs e)
        {
            timerAroundTheLeague.Interval = 10000;
            if (m_gamelist != null && m_gamelist.Games.Count > 0)
            {
                Random rnd = new Random();
                int index = rnd.Next(m_gamelist.Games.Count);
                Game game = m_gamelist.Games[index];
                string news = "";
                switch (game.Status.Indicator.Category)
                {
                    case Indicator.IndicatorCategoy.INTERRUPTED:
                        news = game.AwayTeam.Name + " vs " + game.HomeTeam.Name + "              R";
                        txtNewsgamePbp.Text = "";
                        pictNewsStadium.Visible = false;
                        break;

                    case Indicator.IndicatorCategoy.TERMINATED:
                        news = game.AwayTeam.Name + " " + game.Linescore.GetAwayLineScore().Runs.ToString()
                            + ", " + game.HomeTeam.Name + " " + game.Linescore.GetHomeLineScore().Runs.ToString()
                            + "              F";
                            if (game.Status.WinningPitcher.FullName.Trim() != "")
                            {
                                news += Environment.NewLine + Environment.NewLine
                                + "W: " + game.Status.WinningPitcher.FullName
                                + " (" + game.Status.WinningPitcher.Wins + " - "
                                + game.Status.WinningPitcher.Losses + ", "
                                + game.Status.WinningPitcher.ERA
                                + ")"
                                + Environment.NewLine
                                + "L: " + game.Status.LosingPitcher.FullName
                                + " (" + game.Status.LosingPitcher.Wins + " - "
                                + game.Status.LosingPitcher.Losses + ", "
                                + game.Status.LosingPitcher.ERA
                                + ")";
                                if (game.Status.SavingPitcher.FullName.Trim() != "")
                                {
                                    news += Environment.NewLine
                                        + "S: " + game.Status.SavingPitcher.FullName
                                        + " (" + game.Status.SavingPitcher.Saves + ", "
                                        + game.Status.SavingPitcher.ERA
                                        + ")";
                                }
                            }
                        txtNewsgamePbp.Text = "";
                        pictNewsStadium.Visible = false;
                        txtNewsgamePbp.Visible = false;
                        break;

                    case Indicator.IndicatorCategoy.IN_PROGRESS:
                        string stat = "bot";
                        txtNewsgamePbp.Visible = true;
                        if (game.Status.InningTop)
                        {
                            stat = "top ";
                        }
                        news = game.AwayTeam.Name + " " + game.Linescore.GetAwayLineScore().Runs.ToString()
                            + ", " + game.HomeTeam.Name + " " + game.Linescore.GetHomeLineScore().Runs.ToString()
                            + "              " + stat + " " + game.Status.Inning;
                        txtNewsgamePbp.Text = game.Status.LastPbp;
                        pictNewsStadium.Visible = true;

                        string key = "";
                        if (game.Status.RunnersOnBase[CoreConstants.FIRST_BASE] != null)
                        {
                            key += "1";
                        }
                        else
                        {
                            key += "0";
                        }
                        if (game.Status.RunnersOnBase[CoreConstants.SECOND_BASE] != null)
                        {
                            key += "1";
                        }
                        else
                        {
                            key += "0";
                        }
                        if (game.Status.RunnersOnBase[CoreConstants.THIRD_BASE] != null)
                        {
                            key += "1";
                        }
                        else
                        {
                            key += "0";
                        }
                        pictNewsStadium.Image = listNewsStadium.Images[key];
                        pictNewsStadium.Refresh();
                        break;
                    case Indicator.IndicatorCategoy.NEXT:
                        news = game.AwayTeam.Name + " vs " + game.HomeTeam.Name + ", " + game.StartTime;
                        txtNewsgamePbp.Text = "";
                        pictNewsStadium.Visible = false;
                        break;
                    case Indicator.IndicatorCategoy.WARMUP:
                        news = game.AwayTeam.Name + " vs " + game.HomeTeam.Name + ", " + game.StartTime;
                        txtNewsgamePbp.Text = "";
                        pictNewsStadium.Visible = false;
                        break;
                }
                lblNewsGame.Text = news;
                lblNewsGame.Refresh();
            }
        }

        /// <summary>
        /// Manage the closing of the main form
        /// </summary>
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            MainFormClosing(this, null);
        }

        /// <summary>
        /// Manage a tick of the news timer
        /// </summary>
        private void timerNews_Tick_1(object sender, EventArgs e)
        {
            Random rnd = new Random();
            int num = rnd.Next(100);
            if (num > 90)
            {
                lblNewsTitle.Text = "MLB History";
                txtNews.Text = m_currentHistory[rnd.Next(m_currentHistory.Length)];
            }
            else
            {
                lblNewsTitle.Text = "News";
                txtNews.Text = m_currentNews[rnd.Next(m_currentNews.Count)].Content;
            }
            txtNews.Refresh();
        }

        /// <summary>
        /// Manage a tick of the news timer
        /// </summary>
        private void timerAtTheMound_Tick(object sender, EventArgs e)
        {
            timerAtTheMound.Interval = 10000;
            if (pbAtTheMound.Visible == true)
            {
                pbAtTheMound.Visible = false;
                lblOnTheMoundTitle.Text = m_pitchingTeam.City + " Pitching";
                if (m_inningTop)
                {
                    txtBoxPitchingA.Text = m_homePitchingBoxscore;
                }
                else
                {
                    txtBoxPitchingA.Text = m_awayPitchingBoxscore;
                }
                txtBoxPitchingA.Visible = true;
            }
            else if (m_pitchingTeam!=null)
            {
                pbAtTheMound.Visible = true;
                lblOnTheMoundTitle.Text = "On The Mound For The " + m_pitchingTeam.Name;
                txtBoxPitchingA.Visible = false;
            }
        }

        /// <summary>
        /// Manage a tick of the news timer
        /// </summary>
        private void timerAtTheBat_Tick(object sender, EventArgs e)
        {
            timerAtTheBat.Interval = 10000;
        }

        private void lblMode1_MouseEnter(object sender, EventArgs e)
        {
            Label label = sender as Label;
            label.ForeColor = Color.White;
        }

        private void lblMode1_MouseLeave(object sender, EventArgs e)
        {
            Label label = sender as Label;
            label.ForeColor = Color.Silver;
        }

        private void lblMode1_MouseClick(object sender, MouseEventArgs e)
        {
            Label label = sender as Label;
            switch (label.Text)
            {
                case "L":
                    modeChanged(MODES.LINEUP);
                    break;
                case "F":
                    modeChanged(MODES.FIELD);
                    break;
                case "N":
                    modeChanged(MODES.NEWS);
                    break;
                case "D":
                    modeChanged(MODES.STANDINGS);
                    break;
                case "B":
                    modeChanged(MODES.SCOREBOARDS);
                    break;
                case "S":
                    modeChanged(MODES.STATS);
                    break;
            }
        }

        private void panelStadiumTitle_Paint(object sender, PaintEventArgs e)
        {

        }
    }
}